package com.kc.gb.device.plugins.slant;

import cn.hutool.core.io.FileUtil;
import com.kc.gb.base.dto.Result;
import com.kc.gb.base.dto.DeviceType;
import com.kc.gb.device.common.interfaces.IHardware;
import com.kc.gb.device.common.properties.DeviceProperties;
import com.kc.gb.device.common.utils.SpringHelper;
import com.kc.gb.device.plugins.slant.events.support.SlantPublishEvent;
import com.kc.gb.device.plugins.slant.service.SlantHardwareService;
import com.kc.gb.device.plugins.slant.utils.SlantUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.Charset;
import java.util.Arrays;

@Slf4j
@Service("SLANT")
public class SlantHardware implements IHardware {

    @Resource
    DeviceProperties deviceProperties;

    @Resource
    ThreadPoolTaskScheduler scheduledThreadPoolExecutor;

    @Resource
    SlantHardwareService slantHardwareService;

    private Result INITIALIZE_RESULT = Result.success();

    @Override
    public DeviceType getDeviceType() {
        return DeviceType.SLANT;
    }

    @Override
    public boolean isEnabled() {
        return deviceProperties.isDeviceSlantEnabled();
    }

    @Override
    public Result<?> isConnected() throws Exception {
        return INITIALIZE_RESULT;
    }

    @Override
    public boolean testConnect(String ip, int port) throws Exception {
        return false;
    }

    @Override
    public Result<?> initialize() throws Exception {
        // 斜顶机构使用 UDP 连接，
        String ip  = deviceProperties.getDeviceSlantIP();
        int port = deviceProperties.getDeviceSlantPort();
        DatagramSocket socket = slantHardwareService.connect(ip, port);
        boolean isConnected = socket.isConnected();
        if(isConnected){
            startReceiveMessage(socket);
        }
        return Result.success();
    }

    private void startReceiveMessage(DatagramSocket socket) throws Exception {
        Runnable command = new Runnable() {
            @Override
            public void run() {
                try {
                    // 创建接收数据的缓冲区
                    byte[] buffer = new byte[16];
                    // 创建DatagramPacket对象来接收数据
                    DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                    // 接收数据
                    socket.receive(packet);
                    // 解析接收到的数据
                    String receivedData = SlantUtils.bytesToHex(packet.getData());
                    log.info("Slant|receive data:{}", receivedData);
                    SpringHelper.getApplicationContext().publishEvent(new SlantPublishEvent(receivedData));
                } catch (Exception e) {
                    log.error("Slant|receive data error:{}", e.getMessage(),e);
                }
            }
        };
        scheduledThreadPoolExecutor.scheduleWithFixedDelay(command,0l);
    }

    @Override
    public void afterInitialize(Result<?> result) throws Exception {
        this.INITIALIZE_RESULT = result;
    }

    @Override
    public void stopConnect() {

    }

    public static String getRootPath(Class<?> clazz) {
        String path = clazz.getProtectionDomain().getCodeSource().getLocation().getPath();
        File root = new File(path);
        String rootPath = root.getParentFile().getPath();
        if (rootPath.endsWith("target")) {
            rootPath = rootPath + File.separator + "classes";
        }
        log.info("light control##rootPath=" + rootPath);
        return rootPath;
    }

    private void writeIpIndexFile(Class<?> clazz,String ip,String port,String deviceId) throws IOException {
        String filePath = getRootPath(clazz);
        log.info("light control##IPINDEX filePath:{}", filePath);
        File file = new File(filePath, "IPINDEX");
        if (!file.exists()) {
            file.createNewFile();
        }
        String deviceData = deviceId + " " + port + " " + ip;
        FileUtil.writeLines(Arrays.asList(deviceData), file, Charset.defaultCharset());
    }
}
